﻿using DotnetSpider;
using DotnetSpider.Common;
using DotnetSpider.DataFlow.Parser;
using DotnetSpider.DataFlow.Parser.Attribute;
using DotnetSpider.DataFlow.Parser.Formatter;
using DotnetSpider.DataFlow.Storage.Model;
using DotnetSpider.Downloader;
using DotnetSpider.EventBus;
using DotnetSpider.Scheduler.Component;
using DotnetSpider.Selector;
using DotnetSpider.Statistics;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CrawlerSpiderConsole
{
    public class EntitySpider : Spider
    {
        public static async Task RunAsync()
        {
            //var builder = new SpiderHostBuilder().Register<GithubSpider>();
            //builder.ConfigureAppConfiguration
            //builder.UseSerilog();
            //builder.UseQueueDistinctBfsScheduler<HashSetDuplicateRemover>();
            //await builder.Build().RunAsync();
        }

        public EntitySpider(IEventBus eventBus, IStatisticsService statisticsService,
         SpiderOptions options, ILogger<Spider> logger, IServiceProvider services)
         : base(eventBus, statisticsService, options, logger, services)
        {

        }


        protected override void Initialize()
        {
            AddDataFlow(new DataParser<CnblogsEntry>());
            AddDataFlow(GetDefaultStorage());
            AddRequests(
                new Request("https://news.cnblogs.com/n/page/1/", new Dictionary<string, string> { { "网站", "博客园" } }),
                new Request("https://news.cnblogs.com/n/page/2/", new Dictionary<string, string> { { "网站", "博客园" } }));
        }

        //protected override (string Id, string Name) GetIdAndName()
        //{
        //    return (Guid.NewGuid().ToString(), "博客园");
        //}

        [Schema("cnblogs", "news")]
        [EntitySelector(Expression = ".//div[@class='news_block']", Type = SelectorType.XPath)]
        [GlobalValueSelector(Expression = ".//a[@class='current']", Name = "类别", Type = SelectorType.XPath)]
        [FollowSelector(XPaths = new[] { "//div[@class='pager']" })]
        public class CnblogsEntry : EntityBase<CnblogsEntry>
        {
            protected override void Configure()
            {
                HasIndex(x => x.Title);
                HasIndex(x => new { x.WebSite, x.Guid }, true);
            }

            public int Id { get; set; }

            [Required]
            [StringLength(200)]
            [ValueSelector(Expression = "类别", Type = SelectorType.Enviroment)]
            public string Category { get; set; }

            [Required]
            [StringLength(200)]
            [ValueSelector(Expression = "网站", Type = SelectorType.Enviroment)]
            public string WebSite { get; set; }

            [StringLength(200)]
            [ValueSelector(Expression = "//title")]
            [ReplaceFormatter(NewValue = "", OldValue = " - 博客园")]
            public string Title { get; set; }

            [StringLength(40)]
            [ValueSelector(Expression = "GUID", Type = SelectorType.Enviroment)]
            public string Guid { get; set; }

            [ValueSelector(Expression = ".//h2[@class='news_entry']/a")]
            public string News { get; set; }

            [ValueSelector(Expression = ".//h2[@class='news_entry']/a/@href")]
            public string Url { get; set; }

            [ValueSelector(Expression = ".//div[@class='entry_summary']")]
            public string PlainText { get; set; }

            [ValueSelector(Expression = "DATETIME", Type = SelectorType.Enviroment)]
            public DateTime CreationTime { get; set; }
        }
    }
}
